package org.lds.hotkey.console.business.appinstance.service.impl;

import org.apache.commons.lang3.BooleanUtils;
import org.lds.hotkey.common.model.dto.ResultDTO;
import org.lds.hotkey.common.util.AssertUtil;
import org.lds.hotkey.console.business.app.entity.App;
import org.lds.hotkey.console.business.app.model.request.AppBaseCreateRequest;
import org.lds.hotkey.console.business.app.model.request.AppBaseGetByKeyRequest;
import org.lds.hotkey.console.business.app.model.request.AppBaseUpdateRequest;
import org.lds.hotkey.console.business.app.model.response.AppBaseResponse;
import org.lds.hotkey.console.business.app.service.AppBaseService;
import org.lds.hotkey.console.business.appinstance.entity.AppInstance;
import org.lds.hotkey.console.business.appinstance.model.request.AppInstanceBaseCreateRequest;
import org.lds.hotkey.console.business.appinstance.model.request.AppInstanceBaseGetByKeyRequest;
import org.lds.hotkey.console.business.appinstance.model.request.AppInstanceBaseUpdateRequest;
import org.lds.hotkey.console.business.appinstance.service.AppInstanceBaseService;
import org.lds.hotkey.console.business.appinstance.service.AppInstanceRemoteService;
import org.lds.hotkey.console.common.enums.ConsoleErrorEnum;
import org.lds.hotkey.console.remote.model.request.AppInstanceRegisterRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Objects;

@Service
public class AppInstanceRemoteServiceImpl implements AppInstanceRemoteService {
    @Autowired
    private AppBaseService appBaseService;

    @Autowired
    private AppInstanceBaseService appInstanceBaseService;

    @Override
    public ResultDTO<Long> registerAppInstance(AppInstanceRegisterRequest request) {
        Long appId = saveAppIfNeed(request.getAppName());
        AssertUtil.assertTrue(Objects.nonNull(appId), ConsoleErrorEnum.APP_NAME_NOT_EXIST);

        request.setAppId(appId);
        saveAppInstanceIfNeed(request);
        return ResultDTO.success(appId);
    }

    private Long saveAppIfNeed(String appName) {
        Long appId = getAppId(appName);
        if (Objects.nonNull(appId)) return appId;

        ResultDTO<AppBaseResponse> resultDTO = appBaseService.createApp(AppBaseCreateRequest.builder().name(appName).build());
        if (resultDTO.isSuccess()) return resultDTO.getData().getId();

        return getAppId(appName);
    }

    private Long getAppId(String appName) {
        App app = appBaseService.getAppByKey(AppBaseGetByKeyRequest.builder().name(appName).build());
        if (Objects.isNull(app)) return null;

        // 自动上线
        if (BooleanUtils.isFalse(app.getEnable())) {
            appBaseService.updateApp(AppBaseUpdateRequest.builder().id(app.getId()).enable(true).build());
        }
        return app.getId();
    }

    private void saveAppInstanceIfNeed(AppInstanceRegisterRequest request) {
        AppInstance appInstance = appInstanceBaseService.getAppInstanceByKey(AppInstanceBaseGetByKeyRequest.builder()
                        .appId(request.getAppId())
                        .ip(request.getIp())
                        .port(request.getPort())
                        .build());
        if (Objects.nonNull(appInstance)) {
            // 自动上线
            if (BooleanUtils.isFalse(appInstance.getEnable())) {
                appInstanceBaseService.updateAppInstance(AppInstanceBaseUpdateRequest.builder().id(appInstance.getId()).enable(true).build());
            }
            return;
        }

        appInstanceBaseService.createAppInstance(AppInstanceBaseCreateRequest.builder()
                .appId(request.getAppId())
                .ip(request.getIp())
                .port(request.getPort())
                .build());
    }
}
